/**
 * @file : main.cpp
 * @author: fenghuwuyu
 * @version 1.0
 * @mail: 3148107006@qq.com
 * @date: 2021年04月19日 星期一 16时16分04秒
 * @brief:
 */

#include "RHS.h"
#include "TimeIntegrator.h"
#include <fstream>
#include <cstdlib>


int main()
{
	// the hole code block is used to read variables.
	std::ifstream infile; // infile ifstream 
	infile.open("Inputfile.txt", std::ios::in); // open Inputfile

	std::string t; // tmp string

	std::string method; // method 
	int order = 3; // order 
	long double T1 = 1.0; // T1 
	long double dt = 2.0; // dt (just is k)
	std::string line; // string to storage the getline function
	if (infile.is_open())
	{
		// read the first line 
		getline(infile, line);
		for(int i=0;i<line.size();i++)
		{
			if(line[i] == ':')
			{
				for(int j=i+1;j<line.size();j++)
				{
					method[j-i-1] = line[j];
				}
				break;
			}
			else
			{
				// DO NOTHING
			}
		}

		// read the second line 
		getline(infile, line);
		for(int i=0;i<line.size();i++)
		{
			if(line[i] == ':')
			{
				for(int j=i+1;j<line.size();j++)
				{
					t.push_back(line[j]);
				}
				order = stoi(t);
				break;
			}
			else
			{
				// DO NOTHING
			}
		}
		t.clear();

		// read the third line 
		getline(infile, line);
		for(int i=0;i<line.size();i++)
		{
			if(line[i] == ':')
			{
				for(int j=i+1;j<line.size();j++)
				{
					t.push_back(line[j]);
				}
				T1 = stold(t);
				break;
			}
			else
			{
				// DO NOTHING
			}
		}
		t.clear();
		line.clear();

		// read the last line 
		getline(infile, line);
		for(int i=0;i<line.size();i++)
		{
			if(line[i] == ':')
			{
				for(int j=i+1;j<line.size();j++)
				{
					t.push_back(line[j]);
				}
				dt = stold(t);
				break;
			}
			else
			{
				// DO NOTHING
			}
		}
		t.clear();
		line.clear();
	}
	// std::cout << method[0] <<std::endl;
	// std::cout << order << std::endl;
	// std::cout << T1 << std::endl;
	// std::cout << dt << std::endl;
	// the code above is used to test variables' correction
	// 
	// then we have read the variables that Inputfile gives, which contains: method, order, T, dt 

/**
	AB<2> MyAB_2;
	std::vector<double> U0(6);
	U0[0] = 0.994;
	U0[1] = 0.0;
	U0[2] = 0.0;
	U0[3] = 0.0;
	U0[4] = -2.00158;
	U0[5] = 0.0;
	MyAB_2.initial_value(U0);
	MyAB_2.Set_k(0.00001);
	MyAB_2.Set_T(17.06521);
	MyAB_2.Compute();
	std::vector<double> P;
	P = MyAB_2.Get_beta();
	std::cout << MyAB_2.Get_p() << std::endl;
	std::cout << P[0] << std::endl;
	std::cout << P[1] << std::endl;
	std::cout << P[2] << std::endl;
	std::cout << MyAB_2.Get_n() << std::endl;

	std::vector<std::vector<double>> U1 = MyAB_2.Get_U();
	std::ofstream outfile("Result.txt", std::ios::trunc | std::ios::out);
	for(int j=0;j<=MyAB_2.Get_n();j++)
	{
		for(int i=0;i<2;i++)
		{
			outfile << U1[j][i] << " " ;
		}
		outfile << "" << std::endl;
	}
*/

	// MyAB_2.Print_U();

	/**
	RK MyRK_2;
	std::vector<double> U0(6);
	U0[0] = 0.994;
	U0[1] = 0;
	U0[2] = 0;
	U0[3] = 0;
	U0[4] = -2.00158;
	U0[5] = 0;
	MyRK_2.initial_value(U0);
	MyRK_2.Set_k(0.00001);
	MyRK_2.Set_T(17.06521);
	MyRK_2.Compute();
	std::cout << MyRK_2.Get_n() << std::endl;
	std::vector<std::vector<double>> U1 = MyRK_2.Get_U();
	std::ofstream outfile("Result.txt", std::ios::trunc | std::ios::out);
	for(int j=0;j<=MyRK_2.Get_n();j++)
	{

		for(int i=0;i<2;i++)
		{
			outfile << U1[j][i] << " " ;
		}
		outfile << "" << std::endl;
	}

	// MyRK_2.Print_U();
 */ 
	AM<4> MyAM_2;
	std::vector<double> U0(6);
	U0[0] = 0.994;
	U0[1] = 0;
	U0[2] = 0;
	U0[3] = 0;
	U0[4] = -2.00158;
	U0[5] = 0;
	MyAM_2.initial_value(U0);
	MyAM_2.Set_k(0.001);
	MyAM_2.Set_T(17.065);
	MyAM_2.Compute();
	std::vector<double> P;
	//P = MyAM_2.Get_beta();
	std::cout << MyAM_2.Get_n() << std::endl;
	//std::cout << P[0] << std::endl;
	//std::cout << P[1] << std::endl;
	//std::cout << P[2] << std::endl;
	//std::cout << MyAM_2.Get_n() << std::endl;
	std::vector<std::vector<double>> U1 = MyAM_2.Get_U();
	std::ofstream outfile("Result.txt", std::ios::trunc | std::ios::out);
	for(int j=0;j<=MyAM_2.Get_n();j++)
	{

		for(int i=0;i<2;i++)
		{
			outfile << U1[j][i] << " " ;
		}
		outfile << "" << std::endl;
	}

	//MyAM_2.Print_U();
	/**
	BDF<4> MyBDF_2;
	std::vector<double> U0(6);
	U0[0] = 0.994;
	U0[1] = 0;
	U0[2] = 0;
	U0[3] = 0;
	U0[4] = -2.00158;
	U0[5] = 0;
	*/ 
/**	std::vector<double> U1(6);
	U1[0] = 1;
	U1[1] = 0;
	U1[2] = 0;
	U1[3] = 0;
	U1[4] = -1;
	U1[5] = 0;

	MyBDF_2.initial_value(U0);
	MyBDF_2.Set_k(0.001);
	MyBDF_2.Set_T(17.065);
	std::vector<double> P;
	std::vector<std::vector<double>> Q;
	Q = MyBDF_2.Get_U();
	Q.push_back(U1);

	std::cout << Q[1][0] << std::endl;
	std::cout << Q[1][1] << std::endl;
	for(int i=0;i<10;i++)
	{
		P = MyBDF_2.Newton2(Q, 0);
		Q[1].swap(P);
		P.clear();
		P.resize(6);
		std::cout << Q[1][0] << std::endl;
		std::cout << Q[1][1] << std::endl;
	}
	MyBDF_2.Compute();
	std::cout << MyBDF_2.Get_n() << std::endl;
	// MyBDF_2.Print_U(); 
	std::vector<std::vector<double>> U1 = MyBDF_2.Get_U();
	std::ofstream outfile("Result.txt", std::ios::trunc | std::ios::out);
	for(int j=0;j<=MyBDF_2.Get_n();j++)
	{

		for(int i=0;i<2;i++)
		{
			outfile << U1[j][i] << " " ;
		}
			outfile << "" << std::endl;
	}
*/ 



	return 0;
}
